home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_12_03
/
kamradt
/
mempool.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-07
|
3KB
|
158 lines
// listing 2.
#include "mempool.h"
MemoryPoolLink::
MemoryPoolLink(
size_t size,
MemoryPoolLink *_next)
: bits(0l),
data(new
char[size*PoolSize]),
next(_next)
{
;
}
MemoryPoolLink::
~MemoryPoolLink()
{
delete[] data;
}
void *MemoryPoolLink::malloc(
size_t size)
{
static char lookup[] = {
0, 1, 0, 2,
0, 1, 0, 3,
0, 1, 0, 2,
0, 1, 0, 4,
};
int shift = 0;
unsigned long b = bits;
if((b&0xFFFF) == 0xFFFF)
{
shift = 16;
b >>= 16;
}
if((b&0xFF) == 0xFF)
{
shift += 8;
b >>= 8;
}
if((b&0xF) == 0xF)
{
shift += 4;
b >>= 4;
}
shift += lookup[b&0xF];
bits |= (1l << shift);
return data +
(shift * size);
}
void MemoryPoolLink::free(
void *ptr,
size_t size)
{
bits &=
~(1l <<
((char *)ptr-data)/size);
}
MemoryPool::MemoryPool(
size_t _size)
: size(_size),
freeHead(0,NULL),
usedHead(0,NULL)
{
}
void *MemoryPool::add()
{
MemoryPoolLink *temp = new
MemoryPoolLink(size,
freeHead.next);
if(temp == NULL)
return NULL;
freeHead.next = temp;
return
freeHead.next->
malloc(size);
}
void *MemoryPool::malloc()
{
if(freeHead.next)
{
void *ret =
freeHead.next->
malloc(size);
if(freeHead.next->bits ==
0xFFFFFFFFL)
{
MemoryPoolLink *temp =
freeHead.next;
freeHead.next =
temp->next;
temp->next =
usedHead.next;
usedHead.next = temp;
}
return ret;
}
return add();
}
void MemoryPool::free(
void *ptr)
{
MemoryPoolLink *temp =
freeHead.next;
MemoryPoolLink *prev =
&freeHead;
while(temp)
{
ptrdiff_t diff =
temp->data -
(char *)ptr;
if(diff > 0 &&
diff < size*PoolSize)
{
temp->free(ptr, size);
if(temp->bits == 0l)
{
prev->next =
temp->next;
delete temp;
}
return;
}
prev = temp;
temp = temp->next;
}
temp = usedHead.next;
prev = &usedHead;
while(temp)
{
ptrdiff_t diff =
temp->data -
(char *)ptr;
if(diff > 0 &&
diff < size*PoolSize)
{
temp->free(ptr, size);
prev->next =
temp->next;
temp->next =
freeHead.next;
freeHead.next =
temp;
return;
}
prev = temp;
temp = temp->next;
}
}